---
import OwnersList from '@components/Lists/OwnersList';
import PillListFlat from '@components/Lists/PillListFlat';
import RepositoryList from '@components/Lists/RepositoryList.astro';
import VersionList from '@components/Lists/VersionList.astro';
import { getUbiquitousLanguage, getMessagesForDomain, getParentDomains } from '@utils/collections/domains';
import CustomSideBarSectionList from '@components/Lists/CustomSideBarSectionList.astro';
import { getOwner } from '@utils/collections/owners';
import { buildUrl } from '@utils/url-builder';
import type { CollectionEntry } from 'astro:content';
import { ScrollText, Workflow } from 'lucide-react';
import { isChangelogEnabled, isVisualiserEnabled } from '@utils/feature';

interface Props {
  domain: CollectionEntry<'domains'>;
}

const { domain } = Astro.props;

// @ts-ignore
const services = (domain.data.services as CollectionEntry<'services'>[]) || [];
// @ts-ignore
const subDomains = (domain.data.domains as CollectionEntry<'domains'>[]) || [];

// @ts-ignore
const entities = (domain.data.entities as CollectionEntry<'entities'>[]) || [];

const attachments = domain.data.attachments || [];

const ubiquitousLanguage = await getUbiquitousLanguage(domain);
const hasUbiquitousLanguage = ubiquitousLanguage.length > 0;
const ubiquitousLanguageDictionary = hasUbiquitousLanguage ? ubiquitousLanguage[0].data.dictionary : [];

const ownersRaw = domain.data?.owners || [];
const owners = await Promise.all<ReturnType<typeof getOwner>>(ownersRaw.map(getOwner));
const filteredOwners = owners.filter((o) => o !== undefined);

const messagesForDomain = await getMessagesForDomain(domain);

const resourceGroups = domain.data?.resourceGroups || [];

const parentDomains = await getParentDomains(domain);

const serviceList = services.map((p) => ({
  label: p.data.name,
  badge: p.collection,
  tag: `v${p.data.version}`,
  collection: p.collection,
  href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
}));

const subDomainList = subDomains.map((p) => ({
  label: p.data.name,
  badge: p.collection,
  tag: `v${p.data.version}`,
  collection: p.collection,
  href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
}));

const parentDomainList = parentDomains.map((p) => ({
  label: p.data.name,
  badge: p.collection,
  tag: `v${p.data.version}`,
  collection: p.collection,
  href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
}));

const sendsList = messagesForDomain.sends
  .sort((a, b) => a.collection.localeCompare(b.collection))
  .map((p) => ({
    label: p.data.name,
    badge: p.collection,
    tag: `v${p.data.version}`,
    collection: p.collection,
    href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
  }));

const receivesList = messagesForDomain.receives
  .sort((a, b) => a.collection.localeCompare(b.collection))
  .map((p) => ({
    label: p.data.name,
    badge: p.collection,
    tag: `v${p.data.version}`,
    collection: p.collection,
    href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
  }));

const ubiquitousLanguageList = ubiquitousLanguageDictionary?.map((l) => ({
  label: l.name,
  badge: 'Ubiquitous Language',
  collection: 'ubiquitousLanguages',
  href: buildUrl(`/docs/${domain.collection}/${domain.data.id}/language?id=${l.id}`),
}));

const entityList = entities.map((p) => ({
  label: p.data.name,
  badge: p.collection,
  tag: `v${p.data.version}`,
  collection: p.collection,
  href: buildUrl(`/docs/${p.collection}/${p.data.id}/${p.data.version}`),
}));

const ownersList = filteredOwners.map((o) => ({
  label: o.data.name,
  type: o.collection,
  badge: o.collection === 'users' ? o.data.role : 'Team',
  avatarUrl: o.collection === 'users' ? o.data.avatarUrl : '',
  href: buildUrl(`/docs/${o.collection}/${o.data.id}`),
}));

const attachmentsList = attachments.map((a) => {
  const attachmentIsURL = typeof a === 'string';

  return {
    label: attachmentIsURL ? a : (a.title ?? a.url),
    href: attachmentIsURL ? a : a.url,
    icon: attachmentIsURL ? 'ExternalLinkIcon' : (a.icon ?? 'ExternalLinkIcon'),
    target: '_blank' as const,
    subgroup: attachmentIsURL ? undefined : (a.type ?? ''),
  };
});

const shouldRenderSideBarSection = (section: string) => {
  if (!domain.data.detailsPanel) {
    return true;
  }
  // @ts-ignore
  return domain.data.detailsPanel[section]?.visible ?? true;
};
---

<aside class="sticky top-28 left-0 space-y-8 h-full overflow-y-auto py-4">
  <div>
    {
      parentDomains.length > 0 && shouldRenderSideBarSection('parentDomains') && (
        <PillListFlat
          title={`Parent domains (${parentDomains.length})`}
          pills={parentDomainList}
          emptyMessage={`This domain does not have any parent domains.`}
          color="pink"
          icon="ServerIcon"
          client:load
        />
      )
    }

    {
      subDomains.length > 0 && shouldRenderSideBarSection('subdomains') && (
        <PillListFlat
          title={`Subdomains (${subDomains.length})`}
          pills={subDomainList}
          emptyMessage={`This domain does not contain any subdomains.`}
          color="pink"
          icon="ServerIcon"
          client:load
        />
      )
    }
    {
      resourceGroups
        .filter((section) => section.items.length > 0 && section.sidebar)
        .map((section) => <CustomSideBarSectionList section={section} />)
    }
    {
      shouldRenderSideBarSection('services') && (
        <PillListFlat
          title={`Services (${services.length})`}
          pills={serviceList}
          emptyMessage={`This domain does not contain any services.`}
          color="pink"
          client:load
        />
      )
    }
    {
      shouldRenderSideBarSection('messages') && (
        <PillListFlat
          title={`Sends messages (${sendsList.length})`}
          pills={sendsList}
          emptyMessage={`This domain does not send any messages.`}
          color="orange"
          client:load
        />
      )
    }
    {
      shouldRenderSideBarSection('messages') && (
        <PillListFlat
          title={`Receives messages (${receivesList.length})`}
          pills={receivesList}
          emptyMessage={`This domain does not receive any messages.`}
          color="orange"
          client:load
        />
      )
    }
    {
      ubiquitousLanguageList && hasUbiquitousLanguage && shouldRenderSideBarSection('ubiquitousLanguage') && (
        <PillListFlat
          title={`Ubiquitous Language Dictionary (${ubiquitousLanguageDictionary?.length})`}
          pills={ubiquitousLanguageList}
          color="pink"
          limit={4}
          emptyMessage={`This domain does not have any documented ubiquitous language.`}
          client:load
        />
      )
    }
    {
      entities.length > 0 && shouldRenderSideBarSection('entities') && (
        <PillListFlat
          title={`Entities (${entities.length})`}
          pills={entityList}
          emptyMessage={`This domain does not contain any entities.`}
          color="pink"
          client:load
        />
      )
    }
    {
      domain.data.versions && shouldRenderSideBarSection('versions') && (
        <VersionList versions={domain.data.versions} collectionItem={domain} />
      )
    }
    {
      domain.data.attachments && shouldRenderSideBarSection('attachments') && (
        <PillListFlat
          title={`Attachments (${attachmentsList.length})`}
          pills={attachmentsList}
          emptyMessage={`This domain does not have any attachments.`}
          color="pink"
          client:load
        />
      )
    }
    {
      domain.data.repository && shouldRenderSideBarSection('repository') && (
        <RepositoryList repository={domain.data.repository?.url} language={domain.data.repository?.language} />
      )
    }
    {
      shouldRenderSideBarSection('owners') && (
        <OwnersList
          title={`Owners (${ownersList.length})`}
          owners={ownersList}
          emptyMessage={`This domain does not have any documented owners.`}
          client:load
        />
      )
    }

    <div class="space-y-2">
      {
        isVisualiserEnabled() && (
          <a
            href={buildUrl(`/visualiser/${domain.collection}/${domain.data.id}/${domain.data.version}`)}
            class="flex items-center justify-center space-x-2 text-center rounded-md w-full bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-100/60 hover:text-primary"
          >
            <Workflow strokeWidth={2} size={16} />
            <span class="block">View in visualiser</span>
          </a>
        )
      }
      {
        isChangelogEnabled() && shouldRenderSideBarSection('changelog') && (
          <a
            href={buildUrl(`/docs/${domain.collection}/${domain.data.id}/${domain.data.latestVersion}/changelog`)}
            class="flex items-center space-x-2 justify-center text-center rounded-md w-full bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-100/60 hover:text-primary"
          >
            <ScrollText strokeWidth={2} size={16} />
            <span class="block">Read changelog</span>
          </a>
        )
      }
    </div>
  </div>
</aside>
